<?php

/* $Id$ */

class url {

    /** join base_url and path
     * python urlparse.urljoin() equivalent
     *
     */
    public static function join($base, $path){
        if(empty($path)){
            return $base;
        }
        $base_c = parse_url($base);
        $path_c = parse_url($path);
        if(!empty($path_c['scheme'])){
            return $path;
        }
        if(empty($base_c['scheme'])){
            return $path;
        }

        if($path[0] == '/'){
            // absolute path
            $c = array();
            if(isset($base_c['scheme']  )){ $c['scheme']   = $base_c['scheme']   ;}
            if(isset($base_c['host']    )){ $c['host']     = $base_c['host']     ;}
            if(isset($base_c['port']    )){ $c['port']     = $base_c['port']     ;}
            if(isset($base_c['user']    )){ $c['user']     = $base_c['user']     ;}
            if(isset($base_c['pass']    )){ $c['pass']     = $base_c['pass']     ;}
            if(isset($path_c['path']    )){ $c['path']     = $path_c['path']     ;}
            if(isset($path_c['query']   )){ $c['query']    = $path_c['query']    ;}
            if(isset($path_c['fragment'])){ $c['fragment'] = $path_c['fragment'] ;}
            return self::unparse_url($c);    
        }

        if(empty($base_c['path'])){
            $base_c['path'] = '';
        }
        $t_path = $base_c['path'] . '/' . (isset($path_c['path']) ? $path_c['path'] : '');
        $t_path = str_replace('//', '/', $t_path);
        $t_path = str_replace('/./', '/', $t_path);
        for($i=0;$i<100;$i++){
            if(strpos($t_path, '/..') !== false){
                $t_path = preg_replace("#[^/]+/\.\.#", "", $t_path);
                $t_path = str_replace('//', '/', $t_path);
                continue;
            }
            break;
        }
        for($i=0;$i<100;$i++){
            if(preg_match("#^/\.\./#", $t_path)){
                $t_path = preg_replace("#^/\.\./#", "/", $t_path);
                continue;
            }
            break;
        }
        $t_path = str_replace('//', '/', $t_path);

        // relative path
        $c = array();
        if(isset($base_c['scheme']  )){ $c['scheme']   = $base_c['scheme']   ;}
        if(isset($base_c['host']    )){ $c['host']     = $base_c['host']     ;}
        if(isset($base_c['port']    )){ $c['port']     = $base_c['port']     ;}
        if(isset($base_c['user']    )){ $c['user']     = $base_c['user']     ;}
        if(isset($base_c['pass']    )){ $c['pass']     = $base_c['pass']     ;}
        if(isset($path_c['query']   )){ $c['query']    = $path_c['query']    ;}
        if(isset($path_c['fragment'])){ $c['fragment'] = $path_c['fragment'] ;}
        $c['path'] = $t_path;

        return self::unparse_url($c);    

    }

    public static function unparse_url($parse_url){
        return 
            ((isset($parse_url['scheme'])) ? $parse_url['scheme'] . '://' : '')
            .((isset($parse_url['user'])) ? $parse_url['user'] . ((isset($parse_url['pass'])) ?     ':' . $parse_url['pass'] : '') .'@' : '')
            .((isset($parse_url['host'])) ? $parse_url['host'] : '')
            .((isset($parse_url['port'])) ? ':' . $parse_url['port'] : '')
            .((isset($parse_url['path'])) ? $parse_url['path'] : '')
            .((isset($parse_url['query'])) ? '?' . $parse_url['query'] : '')
            .((isset($parse_url['fragment'])) ? '#' . $parse_url['fragment'] : '')
            ;
    } 

}

/*
$bases = array(
    'http://www.example.com',
    'http://www.example.com',
    'http://www.example.com/',
    'http://www.example.com/bpath1',
    'http://www.example.com/bpath1/',
    'http://www.example.com/bpath1/bpath2',
    'http://www.example.com/bpath1/bpath2/',
);

$paths = array(
    '',
    '/',
    '?action=123',
    '?action=123#click',
    'ppath1/',
    '/ppath1',
    '/ppath1/',
    './ppath1/',
    '../ppath1/ppath',
    '../../ppath1/ppath2/',
);


foreach($bases as $base){
    foreach($paths as $path){
        echo $base . ' --- ' . $path . "\n";
        echo "\t" . url::join($base, $path) . "\n\n";
    }
}

*/
